/*
	Copyright (C) 2009 Salil Bhagurkar
	
	This file is part of ViSE
	
	ViSE is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.
	
	ViSE is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.
	
	You should have received a copy of the GNU Lesser General Public License
	along with ViSE.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <shared.h>

// This is the event registry and management

int notify_new_event(struct node_fs *this, struct node_fs *link);

struct node_fs event = {
	.type = TYPE_FS,
	.name = "event",
	.read = dummy,
	.write = dummy,
	.enumerate = dummy,
	.notify = notify_new_event,
	NODE_FS_INIT_VARS,
	NODE_FS_INIT_INIT,
	NODE_FS_LIST_INIT
};

/*An event generator should register a node with the above event_info in this directory. Upon receiving further events, it should simply modify the contents of the information held by the event_info*/


int notify_new_event(struct node_fs *this, struct node_fs *link)
{
	return 0;
}


/*This is called when the main execution thread gets time to service events*/
int service_event()
{
	struct node_fs *s;
	struct node_fs *listener;
	struct event_info *info;
	arch_block_interrupts();
	s = event.links;
	if(!s) {
		arch_allow_interrupts();
		return -1;
	}
	list_detach(event.links, event.linkstail, event.links);
	arch_allow_interrupts();
	info = (struct event_info *)s->class;
	if(info->count) {
		list_for(info->node->links, listener) {
			listener->write(listener, NULL, info->offset, info->count);
		}
	}
	return 0;
}

int service_events(int nr)
{
	if(nr == 0)
		while(!service_event());
	else {
		while(nr-- && (!service_event()));
	}
	return 0;
}

void init_event_ss()
{
	fs_link("/", &event);
}
